package com.shop.controller;

import com.shop.entity.ShowPageT;
import com.shop.servlet.BaseServlet;
import com.shop.tools.ConstantPool;
import com.shop.tools.StringTo;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * com.angluzha.shop.controller文档说明
 *
 * @author Angluzha
 * @version 2022/9/13
 */
public class BaseController<T> extends HttpServlet {
    HttpServletRequest req;
    HttpServletResponse resp;
    BaseServlet servlet;
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) {
        this.req=req;
        this.resp=resp;
        String uriStr = req.getRequestURI();
        String action = uriStr.substring(uriStr.lastIndexOf("/")+1);
        try {
            String result = getResult(action,req.getParameterMap());
            if (result == null) {
                return;
            }
            String[] splits = result.split("~");
            switch (splits[0]){
                case ConstantPool.GO:
                    resp.sendRedirect(splits[1]);
                    break;
                case ConstantPool.TO:
                    req.getRequestDispatcher(splits[1]).forward(req,resp);
                    break;
                case ConstantPool.JSON:
                    resp.getWriter().write(splits[1]);
                    break;
                default:
                    System.out.println("出错拉");
            }
        }catch (NullPointerException e){
            // 数据无返回值，不做处理
            e.printStackTrace();
            System.out.println("空指针异常");
        } catch (Exception e) {
            //跳转到404
            e.printStackTrace();
            System.out.println("4********0*******4");
        }
    }

    /**
     *
     * @param action 调用的方法名称
     * @param parameterMap Request中所有的Parameter键值对
     * @return  方法运行结果 按String类型接收
     * @throws Exception 方法运行失败
     */
    private String getResult(String action, Map<String, String[]> parameterMap) throws Exception {
        Method[] methods = this.getClass().getDeclaredMethods();
        for (Method method : methods) {
            List<Object> paraList = new ArrayList<>();
            if (method.getName().equals(action)){
                Class<?>[] parameters = method.getParameterTypes();
                for (Class<?> parameter : parameters) {
                    Class<?> clazz = Class.forName(parameter.getName());
                    Object o = clazz.getDeclaredConstructor().newInstance();
                    Field[] fields = clazz.getDeclaredFields();
                    for (int i = 0; i < fields.length; i++) {
                        fields[i].setAccessible(true);
                        Type type = fields[i].getGenericType();
                        String[] values=parameterMap.get(fields[i].getName());
                        Class<?> paraClazz = Class.forName(type.getTypeName());
                        if (values!=null&&!"null".equals(values[0])&&!"".equals(values[0])){
                            fields[i].set(o,StringTo.everObject(values[0],paraClazz));
                        }
                    }
                    paraList.add(o);
                }
                return (String) method.invoke(this,paraList.toArray());
            }
        }
        return null;
    }

    /**
     * 重定向
     * @param uri 目标uri
     * @return
     */
    protected String redirect(String uri){
        return ConstantPool.GO+ "~"+uri;
    }

    /**
     * 转发
     * @param uri 目标uri
     * @return
     */
    protected String forward(String uri){
        return ConstantPool.TO+ "~"+uri;
    }
    protected String writeWeb(String json){
        return ConstantPool.JSON+ "~"+json;
    }
    protected void page(ShowPageT<T> pageT,String uri){
        String page = req.getParameter("page");

        if(pageT==null){
            pageT = new ShowPageT<>();
        }
        if(page==null||"".equals(page)){
            page = "1";
        }
        pageT.setPage(Integer.parseInt(page));

        pageT = servlet.selectPage(pageT);
        pageT.setUri(uri);

        req.setAttribute("pageT",pageT);
    }
}
